import 'dart:convert';
import 'dart:developer' as developer;
// import 'dart:html';
import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_application_cyber/tools/cn_common_global.dart';
import 'package:rongcloud_im_wrapper_plugin/rongcloud_im_wrapper_plugin.dart';

import '../../tools/cn_media_util.dart';
import '../../tools/cn_style.dart';
// import '../../util/user_info_datesource.dart' as example;
import '../../tools/cn_cached_image_widget.dart';
// import 'widget_util.dart';

class CnBottomInputBar extends StatefulWidget {
  BottomInputBarDelegate? delegate;
  late _BottomInputBarState state;

  CnBottomInputBar(BottomInputBarDelegate delegate) {
    this.delegate = delegate;
  }

  @override
  _BottomInputBarState createState() =>
      state = _BottomInputBarState(this.delegate);

  void setTextContent(String? textContent) {
    this.state.setText(textContent);
  }

  void refreshUI() {
    this.state._refreshUI();
  }

  void makeReferenceMessage(RCIMIWMessage? message) {
    this.state.makeReferenceMessage(message);
  }

  RCIMIWReferenceMessage? getReferenceMessage() {
    return this.state.referenceMessage;
  }

  void clearReferenceMessage() {
    this.state.clearReferenceMessage();
  }
}

class _BottomInputBarState extends State<CnBottomInputBar> {
  String pageName = "example.BottomInputBar";
  BottomInputBarDelegate? delegate;
  TextField? textField;
  FocusNode focusNode = FocusNode();
  InputBarStatus? inputBarStatus;
  String inputBarText = RCString.BottomTapSpeak;
  TextEditingController? textEditingController;
  RCIMIWMessage? message;
  RCIMIWReferenceMessage? referenceMessage;
  // example.UserInfo? referenceUserInfo;

  _BottomInputBarState(BottomInputBarDelegate? delegate) {
    this.delegate = delegate;
    this.inputBarStatus = InputBarStatus.Normal;
    this.textEditingController = TextEditingController();

    this.textField = TextField(
      onSubmitted: _clickSendMessage,
      controller: textEditingController,
      decoration: InputDecoration(
          border: InputBorder.none, hintText: RCString.BottomInputTextHint),
      focusNode: focusNode,
      autofocus: true,
      maxLines: null,
      keyboardType: TextInputType.text,
    );
  }

  void setText(String? textContent) {
    if (textContent == null) {
      textContent = '';
    }
    this.textEditingController!.text =
        this.textEditingController!.text + textContent;
    this.textEditingController!.selection = TextSelection.fromPosition(
        TextPosition(offset: textEditingController!.text.length));
    _refreshUI();
  }

  void _refreshUI() {
    setState(() {});
  }

  @override
  void initState() {
    super.initState();
    textEditingController!.addListener(() {
      //获取输入的值
      delegate!.onTextChange(textEditingController!.text);
    });
    focusNode.addListener(() {
      if (focusNode.hasFocus) {
        _notifyInputStatusChanged(InputBarStatus.Normal);
      }
    });
  }

  void _clickSendMessage(String messageStr) {
    if (messageStr == null || messageStr.length <= 0) {
      developer.log("clickSendMessage MessageStr 不能为空", name: pageName);
      return;
    }

    if (this.delegate != null) {
      this.delegate!.willSendText(messageStr);
    } else {
      developer.log("没有实现 BottomInputBarDelegate", name: pageName);
    }
    this.textField!.controller!.text = '';
  }

  switchPhrases() {
    developer.log("switchPhrases", name: pageName);
    if (focusNode.hasFocus) {
      focusNode.unfocus();
    }
    InputBarStatus status = InputBarStatus.Normal;
    if (this.inputBarStatus != InputBarStatus.Phrases) {
      status = InputBarStatus.Phrases;
    }
    _notifyInputStatusChanged(status);
  }

  switchVoice() {
    developer.log("switchVoice", name: pageName);
    CnMediaUtil.instance!.requestmiCrophonePermissions();
    InputBarStatus status = InputBarStatus.Normal;
    if (this.inputBarStatus != InputBarStatus.Voice) {
      status = InputBarStatus.Voice;
    }
    _notifyInputStatusChanged(status);
  }

  switchEmoji() {
    developer.log("switchEmoji", name: pageName);
    InputBarStatus status = InputBarStatus.Normal;
    if (this.inputBarStatus != InputBarStatus.Emoji) {
      if (focusNode.hasFocus) {
        focusNode.unfocus();
      }
      status = InputBarStatus.Emoji;
    }
    _notifyInputStatusChanged(status);
  }

  switchExtention() {
    developer.log("switchExtention", name: pageName);
    if (focusNode.hasFocus) {
      focusNode.unfocus();
    }
    InputBarStatus status = InputBarStatus.Normal;
    if (this.inputBarStatus != InputBarStatus.Extention) {
      status = InputBarStatus.Extention;
    }
    if (this.delegate != null) {
      this.delegate!.didTapExtentionButton();
    } else {
      developer.log("没有实现 BottomInputBarDelegate", name: pageName);
    }
    _notifyInputStatusChanged(status);
  }

  _onVoiceGesLongPress() {
    developer.log("_onVoiceGesLongPress", name: pageName);
    CnMediaUtil.instance!.startRecordAudio();
    setState(() {
      this.inputBarText = RCString.BottomTapUp;
    });
    if (this.delegate != null) {
      this.delegate!.willStartRecordVoice();
    } else {
      developer.log("没有实现 BottomInputBarDelegate", name: pageName);
    }
  }

  _onVoiceGesLongPressEnd() {
    developer.log("_onVoiceGesLongPressEnd", name: pageName);
    setState(() {
      this.inputBarText = RCString.BottomTapSpeak;
    });

    if (this.delegate != null) {
      this.delegate!.willStopRecordVoice();
    } else {
      developer.log("没有实现 BottomInputBarDelegate", name: pageName);
    }

    CnMediaUtil.instance!.stopRecordAudio((String? path, int? duration) {
      if (this.delegate != null && path!.length > 0) {
        this.delegate!.willSendVoice(path, duration);
      } else {
        developer.log("没有实现 BottomInputBarDelegate || 录音路径为空", name: pageName);
      }
    });
  }

  _onVoiceGesVerticalDragStart() {
    setState(() {
      this.inputBarText = RCString.BottomReleaseCancel;
    });
  }

  _onVoiceGesVerticalDragEnd() {
    if (this.delegate != null) {
      this.delegate!.willStopRecordVoice();
    } else {
      developer.log("没有实现 BottomInputBarDelegate", name: pageName);
    }

    CnMediaUtil.instance!.stopRecordAudio((String? path, int? duration) {
      // if (this.delegate != null && path!.length > 0) {
      //   this.delegate!.willSendVoice(path, duration);
      // } else {
      //   developer.log("没有实现 BottomInputBarDelegate || 录音路径为空", name: pageName);
      // }
    });

    setState(() {
      this.inputBarText = RCString.BottomTapSpeak;
    });
    developer.log("取消录音！！！！！");
  }

  Widget _getMainInputField() {
    Widget widget;
    if (this.inputBarStatus == InputBarStatus.Voice) {
      widget = Container(
        alignment: Alignment.center,
        child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          child: Text(this.inputBarText, textAlign: TextAlign.center),
          onTapDown: (tapDownDetails) {
            // developer.log("没有实现");
            _onVoiceGesLongPress();
          },
          onTapUp: (tapUpDetails) {
            _onVoiceGesLongPressEnd();
          },
          onVerticalDragStart: (details) {
            _onVoiceGesVerticalDragStart();
          },
          onVerticalDragEnd: (details) {
            _onVoiceGesVerticalDragEnd();
          },
        ),
      );
    } else {
      widget = Container(
        padding: EdgeInsets.fromLTRB(8, 0, 8, 0),
        child: new ConstrainedBox(
          constraints: BoxConstraints(
              // maxHeight: 200.0,
              ),
          child: new SingleChildScrollView(
            scrollDirection: Axis.vertical,
            reverse: true,
            child: this.textField,
          ),
        ),
      );
    }
    return Container(
      height: 40,
      child: Stack(
        children: <Widget>[
          Container(
            padding: EdgeInsets.fromLTRB(8, 8, 8, 8),

            decoration: BoxDecoration(
                color: Color(RCColor.MessageInputBoxBgColor),
                borderRadius: BorderRadius.circular(
                    20)), //border: new Border.all(color: Colors.black54, width: 0.5),
          ),
          widget
        ],
      ),
    );
  }

  void _notifyInputStatusChanged(InputBarStatus status) {
    this.inputBarStatus = status;
    if (this.delegate != null) {
      this.delegate!.inputStatusDidChange(status);
    } else {
      developer.log("没有实现 BottomInputBarDelegate", name: pageName);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.white,
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: <Widget>[
              referenceMessage == null
                  ? Container(
                      height: 1,
                      width: 1,
                    )
                  : _buildReferenceWidget(),
              Row(
                children: <Widget>[
                  IconButton(
                    icon: Image.asset('images/message/ic_voice_color.png'),
                    iconSize: 32,
                    onPressed: () {
                      switchVoice();
                    },
                  ),
                  Expanded(child: _getMainInputField()),
                  IconButton(
                    icon: Image.asset(
                        'images/message/ic_expression_color.png'), // sentiment_ver
                    iconSize: 32,
                    onPressed: () {
                      switchEmoji();
                    },
                  ),
                  IconButton(
                    icon: Image.asset('images/message/ic_add_color.png'),
                    iconSize: 32,
                    onPressed: () {
                      switchExtention();
                    },
                  ),
                ],
              ),
            ]));
  }

  Widget _buildReferenceWidget() {
    return IntrinsicHeight(
        child: Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        VerticalDivider(
          color: Colors.grey,
          thickness: 3,
        ),
        Expanded(
            child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
              Container(
                  margin: EdgeInsets.only(top: 4, bottom: 2),
                  child: Text("",
                      style: TextStyle(
                          fontSize: RCFont.BottomReferenceNameSize,
                          color: Color(RCColor.BottomReferenceNameColor)))),
              ConstrainedBox(
                constraints: BoxConstraints(
                  maxHeight: 60.0,
                ),
                child: new SingleChildScrollView(
                    scrollDirection: Axis.vertical,
                    reverse: false,
                    child: GestureDetector(
                      child: _buildReferenceContent(),
                      onTap: () {
                        _clickContent();
                      },
                    )),
              )
            ])),
        Container(
            margin: EdgeInsets.only(right: 10),
            height: 30,
            width: 30,
            child: IconButton(
              icon: Icon(Icons.close),
              onPressed: () {
                clearReferenceMessage();
              },
            ))
      ],
    ));
  }

  void _clickContent() {
    if (referenceMessage!.referenceMessage is RCIMIWImageMessage) {
      // 引用的消息为图片时的点击事件
      RCIMIWMessage tempMsg = message!;
      tempMsg = referenceMessage!.referenceMessage!;
      Navigator.pushNamed(context, "/image_preview", arguments: tempMsg);
    }
    // else if (referenceMessage!.referMsg is FileMessage) {
    //   // 引用的消息为文件时的点击事件
    //   Message tempMsg = message!;
    //   tempMsg.content = referenceMessage!.referMsg;
    //   Navigator.pushNamed(context, "/file_preview", arguments: tempMsg);
    // } else if (referenceMessage!.referMsg is RichContentMessage) {
    //   // 引用的消息为图文时的点击事件
    //   RichContentMessage richContentMessage = referenceMessage!.referMsg as RichContentMessage;
    //   Map param = {"url": richContentMessage.url, "title": richContentMessage.title};
    //   Navigator.pushNamed(context, "/webview", arguments: param);
    // }
    else {
      // 引用的消息为文本时的点击事件
    }
  }

  Widget _buildReferenceContent() {
    Widget widget = Container(
      height: 1,
      width: 1,
    );
    RCIMIWMessage? messageContent = referenceMessage!.referenceMessage;
    if (messageContent is RCIMIWTextMessage) {
      RCIMIWTextMessage textMessage = messageContent;
      widget = Text(textMessage.text!,
          style: TextStyle(
              fontSize: RCFont.BottomReferenceContentSize,
              color: Color(RCColor.BottomReferenceContentColor)));
    } else if (messageContent is RCIMIWImageMessage) {
      RCIMIWImageMessage imageMessage = messageContent;
      Widget imageWidget;
      if (imageMessage != null &&
          imageMessage!.thumbnailBase64String!.length > 0) {
        Uint8List bytes = base64.decode(imageMessage.thumbnailBase64String!);
        imageWidget = Image.memory(bytes);
      } else {
        if (imageMessage.local != null) {
          String path =
              CnMediaUtil.instance!.getCorrectedLocalPath(imageMessage.local)!;
          File file = File(path);
          if (file != null && file.existsSync()) {
            imageWidget = Image.file(file);
          } else {
            imageWidget = CnCachedNetworkImage(
              progressIndicatorBuilder: (context, url, progress) =>
                  CircularProgressIndicator(
                value: progress!.progress,
              ),
              imageUrl: imageMessage.remote!,
            );
          }
        } else {
          imageWidget = CnCachedNetworkImage(
            progressIndicatorBuilder: (context, url, progress) =>
                CircularProgressIndicator(
              value: progress!.progress,
            ),
            imageUrl: imageMessage.remote!,
          );
        }
      }
      widget = Container(
        constraints: BoxConstraints(
          maxWidth: MediaQuery.of(context).size.width - 150,
        ),
        child: imageWidget,
      );
    }
    // else if (messageContent is FileMessage) {
    //   FileMessage fileMessage = messageContent;
    //   widget = Text("[文件] ${fileMessage.mName}", style: TextStyle(fontSize: RCFont.BottomReferenceContentSize, color: Color(RCColor.BottomReferenceContentColorFile)));
    // } else if (messageContent is RichContentMessage) {
    //   RichContentMessage richContentMessage = messageContent;
    //   widget = Text("[图文] ${richContentMessage.title}", style: TextStyle(fontSize: RCFont.BottomReferenceContentSize, color: Color(RCColor.BottomReferenceContentColorFile)));
    // }
    else if (messageContent is RCIMIWReferenceMessage) {
      RCIMIWReferenceMessage referenceMessage = messageContent;
      widget = Text(referenceMessage.text!,
          style: TextStyle(
              fontSize: RCFont.BottomReferenceContentSize,
              color: Color(RCColor.BottomReferenceContentColorFile)));
    }
    return widget;
  }

  // void setInfo(String? userId) {
  //   example.UserInfo? userInfo = example.UserInfoDataSource.cachedUserMap[userId];
  //   if (userInfo != null) {
  //     this.referenceUserInfo = userInfo;
  //   } else {
  //     example.UserInfoDataSource.getUserInfo(userId).then((onValue) {
  //       setState(() {
  //         this.referenceUserInfo = onValue;
  //       });
  //     });
  //   }
  // }

  void makeReferenceMessage(RCIMIWMessage? message) async {
    if (message != null) {
      this.message = message;

      RCIMIWReferenceMessage? referenceMessage =
          await CnGlobal.engine.createReferenceMessage(
        RCIMIWConversationType.private,
        message.senderUserId!,
        null,
        message,
        '',
      );
      if (message is RCIMIWReferenceMessage) {
        RCIMIWReferenceMessage content = message as RCIMIWReferenceMessage;
        RCIMIWTextMessage? textMessage =
            await CnGlobal.engine.createTextMessage(
          RCIMIWConversationType.private,
          message.senderUserId!,
          null,
          message.text!,
        );
        referenceMessage!.referenceMessage = textMessage;
      } else {
        referenceMessage!.referenceMessage = message;
      }
      // setInfo(referenceMessage.senderUserId);
    } else {
      referenceMessage = null;
    }
    _refreshUI();
  }

  RCIMIWReferenceMessage? getReferenceMessage() {
    return referenceMessage;
  }

  void clearReferenceMessage() {
    referenceMessage = null;
    message = null;
    _refreshUI();
  }
}

enum InputBarStatus {
  Normal, //正常
  Voice, //语音输入
  Extention, //扩展栏
  Phrases, //快捷回复
  Emoji, // emoji输入
}

abstract class BottomInputBarDelegate {
  ///输入工具栏状态发生变更
  void inputStatusDidChange(InputBarStatus status);

  ///即将发送消息
  void willSendText(String text);

  ///即将发送语音
  void willSendVoice(String? path, int? duration);

  ///即将开始录音
  void willStartRecordVoice();

  ///即将停止录音
  void willStopRecordVoice();

  ///点击了加号按钮
  void didTapExtentionButton();

  ///输入框内容变化监听
  void onTextChange(String text);
}
